package com.whjk.system.data.uitls;

import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * * @projectName
 * * @title AnnotationUtil
 * * @package
 * * @description注解工具类
 * * @author IT_CREAT
 * * @date2019 2019/9/14 21:16
 * * @version V1.0.0
 */
@Data
@Accessors(chain = true)
@ToString
public class AnnotationUtil<T> {

    public Class<T> clazz;

    public AnnotationUtil(Class<T> clazz) {
        this.clazz = clazz;
    }

    /**
     * 动态修改对象属性上某个注解的属性值，通过getClazz()方法可以得到修改后的class
     *
     * @param fieldName       对象属性名称
     * @param annotationClass 注解class
     * @param attrName        注解属性名称
     * @param attrValue       注解属性值
     * @return 本工具类实例
     * @throws Exception 异常
     */
/*    public AnnotationUtil updateAnnoAttrValue(String fieldName, Class<? extends Annotation> annotationClass, String attrName, Object attrValue) throws Exception {
        Field[] declaredFields = this.clazz.getDeclaredFields();
        if (declaredFields.length != 0) {
            for (int i = 0; i < declaredFields.length; i++) {
                Field declaredField = declaredFields[i];
                if (fieldName.equals(declaredField.getName())) {
                    InvocationHandler invocationHandler = Proxy.getInvocationHandler(declaredField.getAnnotation(annotationClass));
                    Field hField = invocationHandler.getClass().getDeclaredField("memberValues");
                    hField.setAccessible(true);
                    Map memberValues = (Map) hField.get(invocationHandler);
                    memberValues.put(attrName, attrValue);
                    break;
                }
            }
        }
        return this;
    }*/

    /**
     * 动态修改对象属性上某个注解的属性值，通过getClazz()方法可以得到修改后的class
     *
     * @param fieldNames      字段数组
     * @param annotationClass 注解
     * @param attrNames       属性名数组-和字段依次匹配
     * @param attrValues      属性值数组-和字段依次匹配
     * @return
     * @throws Exception
     */
    public AnnotationUtil updateAnnoAttrValue(String fieldNames, Class<? extends Annotation> annotationClass,
                                              String attrNames, List<String> attrValues) throws Exception {
        if (fieldNames == null ||  attrNames == null || attrValues == null) {
            throw new Exception("参数错误！");
        }
        Field[] declaredFields = this.clazz.getDeclaredFields();
        if (declaredFields.length != 0) {
            HashMap<String, Field> map = new HashMap<>();
            for (int i = 0; i < declaredFields.length; i++) {
                Field declaredField = declaredFields[i];
                map.put(declaredField.getName(), declaredField);
            }
            InvocationHandler invocationHandler = Proxy.getInvocationHandler(map.get(fieldNames).getAnnotation(annotationClass));
            Field hField = invocationHandler.getClass().getDeclaredField("memberValues");
            hField.setAccessible(true);
            Map<String,String[]> memberValues = (Map<String,String[]>) hField.get(invocationHandler);
            String[] array = attrValues.stream().map(String::valueOf).toArray(String[]::new);
            memberValues.put(attrNames, array);

        }
        return this;
    }
}
